package com.svms.movement;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.SerializationUtils;
import org.apache.commons.lang.StringUtils;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Button;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.ListitemRenderer;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;

import com.svms.service.constants.SvmsStatusCodes;
import com.svms.service.vo.MovementVO;
import com.svms.service.vo.TransportVO;
import com.svms.service.vo.VehicleVO;
import com.svms.utils.SvmsMessageUtils;
import com.svms.utils.SvmsWindowUtils;
import com.svms.web.factory.SvmsWebFactory;

public class MovementDialogueCtrl extends GenericForwardComposer implements
		Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	// *********************************************//

	private Window window_movement_dialogue;

	private Textbox txb_start_place;
	private Textbox txb_end_place;
	private Textbox txb_stuffing_place;
	private Textbox txb_distance_traveled;
	private Datebox dtb_trip_start_date;
	private Datebox dtb_trip_end_date;

	private Button btn_add_movement;
	private Button btn_delete_movement;
	private Button btn_edit_movement;
	private Button btn_save_movement;

	private Button btn_cancle;
	private Button btn_close;

	private Listbox lstbx_vehicles;
	private ListModelList<VehicleVO> lst_model_vehicle;

	// *********************************************//

	private ManageMovementCtrl manageMovementCtrl;

	private MovementVO movementVO;
	private MovementVO oldMovementVO;

	public MovementVO getMovementVO() {
		/*
		 * if (movementVO == null) { movementVO = new MovementVO(); VehicleVO
		 * vehicleVO = new VehicleVO(); vehicleVO.setVehicleDocuments(new
		 * HashMap<String, Date>()); movementVO.setVehicleVO(vehicleVO); }
		 */
		return movementVO;
	}

	public void setMovementVO(MovementVO movementVO) {
		this.movementVO = movementVO;
	}

	public MovementVO getOldMovementVO() {
		return oldMovementVO;
	}

	public void setOldMovementVO(MovementVO oldMovementVO) {
		this.oldMovementVO = (MovementVO) SerializationUtils
				.clone(oldMovementVO);
	}

	public MovementDialogueCtrl() {
		super();
	}

	/**
	 * Operation to be performed on load of the window.
	 * 
	 * @param event
	 * @throws Exception
	 */
	public void onCreate$window_movement_dialogue(Event event) throws Exception {

		Map<String, Object> args = SvmsWindowUtils.getCreationArgsMap(event);
		MovementVO selectedMovement = (MovementVO) args.get("selectedMovement");
		// setMovementVO((MovementVO)
		// SerializationUtils.clone(selectedMovement));
		movementVO = (MovementVO) SerializationUtils.clone(selectedMovement);
		manageMovementCtrl = (ManageMovementCtrl) args.get("movementListCtrl");

		// Load Vehicle Dropdown
		lst_model_vehicle = new ListModelList<VehicleVO>(SvmsWebFactory
				.vehicleService().getVehicleList());
		lstbx_vehicles.setModel(lst_model_vehicle);
		lstbx_vehicles.setItemRenderer(new ListitemRenderer() {
			@Override
			public void render(Listitem item, Object data, int index)
					throws Exception {

				final VehicleVO vehicle = (VehicleVO) data;
				Listcell lc = new Listcell(vehicle.getVehicleNumber());
				lc.setParent(item);
				item.setAttribute("selectedVehicle", data);

			}
		});

		if (getMovementVO() == null) {
			// Which means edit in progress. So enable fields to edit
			enableFields();
			loadAddEditScenarioButtons();
			newCustomerMapping();
		} else {
			setOldMovementVO(getMovementVO());
			disableFields();
			loadDefalutScenarioButtons();
			writeBeanToDialogue(getOldMovementVO());
		}

	}

	/**
	 * New customer is create. i.e empty values are set to the fields in the
	 * dialogue box
	 */
	private void newCustomerMapping() {
		setMovementVO(new MovementVO());
		writeBeanToDialogue(getMovementVO());
	}

	/**
	 * Operation to be performed on click of add movement button. It will
	 * loadAddEditScenarioButtons and enables all editable fields
	 * 
	 * @param event
	 */
	public void onClick$btn_add_movement(Event event) {
		oldMovementVO = null;
		newCustomerMapping();
		enableFields();
		loadAddEditScenarioButtons();
	}

	/**
	 * Operation to be performed on click of edit button. It will
	 * loadAddEditScenarioButtons and enables all editable fields
	 * 
	 * @param event
	 */
	public void onClick$btn_edit_movement(Event event) {
		enableFields();
		loadAddEditScenarioButtons();
	}

	/**
	 * Operation to be performed on click of cancel button. It will
	 * loadDefalutScenarioButtons and disables all editable fields
	 * 
	 * @param event
	 */
	public void onClick$btn_cancle(Event event) {
		writeBeanToDialogue(oldMovementVO);
		setMovementVO(oldMovementVO);
		disableFields();
		loadDefalutScenarioButtons();
	}

	public void onClick$btn_close(Event event) {
		setMovementVO(oldMovementVO);
		window_movement_dialogue.detach();
	}

	/**
	 * Operation to be performed on click of save button. It performs the save
	 * operation. It will loadDefalutScenarioButtons and disables all editable
	 * fields on successful save
	 * 
	 * @param event
	 */
	public void onClick$btn_save_movement(Event event) {
		doSave();
	}

	/**
	 * Save operation by calling save method from service
	 */
	private void doSave() {

		writeDialogueToBean();

		MovementVO movementVO = null;

		if (StringUtils.isBlank(getMovementVO().getMovementId())) {
			System.out.println("Insert New Movement invoked");

			movementVO = SvmsWebFactory.movementService().insertNewMovement(
					getMovementVO());

		} else {
			System.out.println("Save Movement invoked");

			movementVO = SvmsWebFactory.movementService().editMovement(
					getMovementVO());

		}

		// Uncomment when adding service call for movement

		/*
		 * if (movementVO.getResultCode().getErrorDetails().size() > 0) {
		 * SvmsMessageUtils.showErrorMessageFromLable(movementVO
		 * .getResultCode().getErrorDetails());
		 * writeBeanToDialogue(getOldMovementVO()); return; }
		 */

		if (false) {

		} else {

			if (manageMovementCtrl.getLstbx_movements() != null) {

				// now synchronize the customer listBox
				final ListModelList lml = (ListModelList) manageMovementCtrl
						.getLstbx_movements().getListModel();

				// Check if the customer object is new or updated
				// -1 means that the obj is not in the list, so it's new.
				if (lml.indexOf(oldMovementVO) == -1) {
					lml.add(getMovementVO());
					System.out.println("Add Movemnt to main vehicle list");
					setOldMovementVO(getMovementVO());
				} else {
					lml.set(lml.indexOf(getOldMovementVO()), getMovementVO());
					System.out.println("save Movemnt to main vehicle list");
					setOldMovementVO(getMovementVO());
				}

			}
			SvmsMessageUtils
					.showSuccessMessage("Movement Was successfully saved to the system");
			disableFields();
			loadDefalutScenarioButtons();
		}

		// call from cusromerList then synchronize the customers listBox

	}

	/**
	 * Operation to be performed on click of cancel button. It will
	 * loadDefalutScenarioButtons and disables all editable fields
	 * 
	 * @param event
	 */
	public void onClick$btn_delete_movement(Event event) {

		writeDialogueToBean();

		MovementVO movementVO;

		if (getMovementVO() != null && getMovementVO().getMovementId() != null) {

			movementVO = SvmsWebFactory.movementService().deleteMovement(
					getMovementVO());

		} else {
			SvmsMessageUtils
					.showErrorMessageFromLable(SvmsStatusCodes.SELECT_VEHICLE_TO_DELETE);
			return;
		}

		/*
		 * if (getMovementVO().getResultCode().getErrorDetails().size() > 0) {
		 * SvmsMessageUtils.showErrorMessageFromLable(vehicleVO
		 * .getResultCode().getErrorDetails()); return; }
		 */if (false) {
		} else {
			SvmsMessageUtils
					.showSuccessMessage("Movement Was successfully deleted from the System");
			disableFields();
			loadDefalutScenarioButtons();
		}

		// call from cusromerList then synchronize the customers listBox
		if (manageMovementCtrl.getLstbx_movements() != null) {

			// now synchronize the customer listBox
			final ListModelList lml = (ListModelList) manageMovementCtrl
					.getLstbx_movements().getListModel();

			// Check if the customer object is new or updated
			// -1 means that the obj is not in the list, so it's new.
			if (lml.indexOf(getOldMovementVO()) == -1) {
				System.out
						.println("Movement not present in main Movement list");
			} else {
				lml.remove(getOldMovementVO());
				System.out.println("Removed Movement from main Movement list");
			}

		}
		window_movement_dialogue.detach();
	}

	/**
	 * To copy the contents form the individual fields in dialogue box to
	 * service for processing
	 * 
	 * @param vehicleVO
	 */
	private void writeDialogueToBean() {

		Listitem listitem = lstbx_vehicles.getSelectedItem();

		if (listitem != null) {
			movementVO.setVehicleVO((VehicleVO) listitem
					.getAttribute("selectedVehicle"));
		}
		movementVO.setStartDate(dtb_trip_start_date.getValue());
		movementVO.setEndDate(dtb_trip_end_date.getValue());
		movementVO.setDistanceTraveled(txb_distance_traveled.getValue());
		movementVO.setStuffingPlace(txb_stuffing_place.getValue());
		movementVO.setStartPlace(txb_start_place.getValue());
		movementVO.setEndPlace(txb_end_place.getValue());

	}

	/**
	 * To copy the contents form the VO to dialogue box. Individual mapping of
	 * values needs to be done.
	 * 
	 * @param movementVO
	 */
	private void writeBeanToDialogue(MovementVO movementVO) {

		// To populate the transport dropdown with all the values in TransporDB

		if (movementVO != null) {

			txb_distance_traveled.setValue(movementVO.getDistanceTraveled());
			txb_end_place.setValue(movementVO.getEndPlace());
			txb_start_place.setValue(movementVO.getStartPlace());
			txb_stuffing_place.setValue(movementVO.getStuffingPlace());
			dtb_trip_end_date.setValue(movementVO.getEndDate());
			dtb_trip_start_date.setValue(movementVO.getStartDate());
			System.out.println("XXX");
			System.out.println(movementVO.getVehicleVO());
			System.out.println(lst_model_vehicle);
			System.out.println("XXX");
			lstbx_vehicles.setSelectedIndex(lst_model_vehicle
					.indexOf(movementVO.getVehicleVO()));

		}

	}

	/**
	 * Enables all the text box so that it can be edited
	 */
	private void enableFields() {
		txb_distance_traveled.setDisabled(false);
		txb_end_place.setDisabled(false);
		txb_start_place.setDisabled(false);
		txb_stuffing_place.setDisabled(false);
		dtb_trip_end_date.setDisabled(false);
		dtb_trip_start_date.setDisabled(false);
		lstbx_vehicles.setDisabled(false);
	}

	/**
	 * Disables all the text box so that it cannot edited
	 */
	private void disableFields() {
		txb_distance_traveled.setDisabled(true);
		txb_end_place.setDisabled(true);
		txb_start_place.setDisabled(true);
		txb_stuffing_place.setDisabled(true);
		dtb_trip_end_date.setDisabled(true);
		dtb_trip_start_date.setDisabled(true);
		lstbx_vehicles.setDisabled(true);
	}

	/**
	 * Will load ADD MOVEMENT scenario CURD buttons.
	 * 
	 */
	private void loadAddEditScenarioButtons() {

		btn_add_movement.setDisabled(true);
		btn_delete_movement.setDisabled(true);
		btn_edit_movement.setDisabled(true);
		btn_save_movement.setDisabled(false);

		btn_cancle.setDisabled(false);
		btn_close.setDisabled(false);
	}

	/**
	 * Will load DEFAULT CURD buttons. Is same for DEFALUT, SAVE, DISCARD
	 */
	private void loadDefalutScenarioButtons() {

		btn_add_movement.setDisabled(false);
		btn_delete_movement.setDisabled(false);
		btn_edit_movement.setDisabled(false);
		btn_save_movement.setDisabled(true);

		btn_cancle.setDisabled(true);
		btn_close.setDisabled(false);
	}

}
